﻿using StandardManager.DB;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace StandardManager.EntityCode
{
    public partial class EntityCodeForm : Form
    {
        #region 属性
        public string EntityDBFileName
        {
            get { return GlobalConfig.Instance.EntityDBFileName; }
        }
        #endregion

        #region 构造函数
        public EntityCodeForm()
        {
            InitializeComponent();
        }
        private void EntityCodeForm_Load(object sender, EventArgs e)
        {
            if (!File.Exists(EntityDBFileName))
            {
                MessageBox.Show("无法访问实体编码表，请设置！");
                return;
            }
            ConnectionDatabase_S2 connectionDatabase_S2 = ConnectionDatabase_S2.BuildSqliteConnection(EntityDBFileName);
            CreateTableIfNotExists(connectionDatabase_S2);

            var dt = connectionDatabase_S2.SelectData("select * from EntityCode");

            Dictionary<string, TreeNode> items = new Dictionary<string, TreeNode>();
            List<EntityCode> leftItems = new List<EntityCode>();
            for (var i = 0; i < dt.Rows.Count; i++)
            {
                EntityCode entityCode = new EntityCode(dt.Rows[i]);
                if (string.IsNullOrEmpty(entityCode.ParentId))
                {
                    TreeNode tn = new TreeNode(entityCode.ToString());
                    tn.Tag = entityCode;
                    this.treeView1.Nodes.Add(tn);
                    items.Add(entityCode.Id, tn);
                }
                else
                {
                    leftItems.Add(entityCode);
                }
            }

            while (leftItems.Count > 0)
            {
                bool hasUpdate = false;
                for (var i = leftItems.Count - 1; i >= 0; i--)
                {
                    if (items.ContainsKey(leftItems[i].ParentId))
                    {
                        TreeNode tn2 = new TreeNode(leftItems[i].ToString());
                        tn2.Tag = leftItems[i];

                        items[leftItems[i].ParentId].Nodes.Add(tn2);
                        items.Add(leftItems[i].Id, tn2);

                        leftItems.RemoveAt(i);

                        hasUpdate = true;
                    }
                }
                if (hasUpdate == false)
                {
                    break;
                }
            }

            SortTree();
        }

        #endregion

        #region 对树进行排序
        private void SortTree(int maxLevelLimit = 1000)
        {
            List<EntityCodeWithTreeNode> items = new List<EntityCodeWithTreeNode>();
            for (var i = 0; i < treeView1.Nodes.Count; i++)
            {
                items.Add(new EntityCodeWithTreeNode() { Item = treeView1.Nodes[i].Tag as EntityCode, TreeNode = treeView1.Nodes[i] });
            }
            items.Sort(new EntityCodeSorter());
            treeView1.Nodes.Clear();
            int currentLevel = 0;
            for (var i = 0; i < items.Count; i++)
            {
                treeView1.Nodes.Add(items[i].TreeNode);

                if (currentLevel < maxLevelLimit)
                    SortTree(items[i].TreeNode, currentLevel + 1, maxLevelLimit);
            }
        }
        private void SortTree(TreeNode treeNode, int currentLevel, int maxLevelLimit = 1000)
        {
            List<EntityCodeWithTreeNode> items = new List<EntityCodeWithTreeNode>();
            for (var i = 0; i < treeNode.Nodes.Count; i++)
            {
                items.Add(new EntityCodeWithTreeNode()
                {
                    Item = treeNode.Nodes[i].Tag as EntityCode,
                    TreeNode = treeNode.Nodes[i]
                });
            }
            items.Sort(new EntityCodeSorter());
            treeNode.Nodes.Clear();
            for (var i = 0; i < items.Count; i++)
            {
                treeNode.Nodes.Add(items[i].TreeNode);

                if (currentLevel < maxLevelLimit)
                    SortTree(items[i].TreeNode, currentLevel + 1, maxLevelLimit);
            }
        }
        #endregion

        private void CreateTableIfNotExists(ConnectionDatabase_S2 connectionDatabase_S2)
        {
            // 创建表的 SQL 语句  
            string createTableQuery = EntityCode.GetTableCreateSql();

            connectionDatabase_S2.ExecuteSQL(createTableQuery);
        }

        private void 新增大类ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_currentSelectNode = null;
            EntityCodeItem form = new EntityCodeItem()
            {
                StartPosition = FormStartPosition.CenterParent,
                CurrentSelectItemLevel = 0,
            };
            form.OnPatchItemAdd += Form_OnPatchItemAdd;
            if (form.ShowDialog() == DialogResult.OK)
            {
                if (form.SelectedItem == null) { return; }
                TreeNode tn = new TreeNode(form.SelectedItem.ToString());
                tn.Tag = form.SelectedItem;
                this.treeView1.Nodes.Add(tn);

                Save(form.SelectedItem);
            }
        }

        private TreeNode m_currentSelectNode;
        private void Form_OnPatchItemAdd(object? sender, EventArgs e)
        {
            var ec = (EntityCode)sender;
            TreeNode tn = new TreeNode(ec.ToString());
            tn.Tag = ec;
            if (m_currentSelectNode == null)
            {
                treeView1.Nodes.Add(tn);
                SortTree();
            }
            else
            {
                m_currentSelectNode.Nodes.Add(tn);
                SortTree(m_currentSelectNode, 0, 0);
            }

            Save(ec);

        }

        private void 新增子类ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }

            var selNode = this.treeView1.SelectedNode;
            m_currentSelectNode = selNode;

            EntityCodeItem form = new EntityCodeItem()
            {
                StartPosition = FormStartPosition.CenterParent,
                ParentItem = selNode.Tag as EntityCode,
                CurrentSelectItemLevel = selNode.Level,
            };
            form.OnPatchItemAdd += Form_OnPatchItemAdd;
            if (form.ShowDialog() == DialogResult.OK)
            {
                if (form.SelectedItem == null) { return; }

                Form_OnPatchItemAdd(form.SelectedItem, null);
            }
        }

        private void 新增同级ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }

            var selNode = this.treeView1.SelectedNode.Parent;
            if (selNode == null) { return; }
            m_currentSelectNode = selNode;

            EntityCodeItem form = new EntityCodeItem()
            {
                StartPosition = FormStartPosition.CenterParent,
                CurrentSelectItemLevel = selNode.Level,
            };
            form.OnPatchItemAdd += Form_OnPatchItemAdd;
            if (form.ShowDialog() == DialogResult.OK)
            {
                if (form.SelectedItem == null) { return; }

                Form_OnPatchItemAdd(form.SelectedItem, null);
            }
        }
        private void 修改ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }

            m_currentSelectNode = this.treeView1.SelectedNode;

            var selNode = this.treeView1.SelectedNode;
            var pNode = this.treeView1.SelectedNode.Parent;
            EntityCodeItem form = new EntityCodeItem()
            {
                StartPosition = FormStartPosition.CenterParent,
                SelectedItem = this.treeView1.SelectedNode.Tag as EntityCode,
                ParentItem = pNode == null ? null : pNode.Tag as EntityCode,
                CurrentSelectItemLevel = selNode.Level,
            };
            if (form.ShowDialog() == DialogResult.OK)
            {
                selNode.Text = form.SelectedItem.ToString();
                SaveUpdate(form.SelectedItem);

                if (pNode == null)
                {
                    SortTree(0);
                }
                else
                {
                    SortTree(pNode, 0, 0);
                }
            }
        }

        #region 数据库Sql
        private void Save(EntityCode item)
        {
            ConnectionDatabase_S2 connectionDatabase_S2 = ConnectionDatabase_S2.BuildSqliteConnection(EntityDBFileName);
            var booksSql = item.BuildInsertSql();
            connectionDatabase_S2.ExecuteSQL(booksSql);
            connectionDatabase_S2.Dispose();
        }

        private void SaveUpdate(EntityCode item)
        {
            ConnectionDatabase_S2 connectionDatabase_S2 = ConnectionDatabase_S2.BuildSqliteConnection(EntityDBFileName);
            var booksSql = item.BuildUpdateSql();
            connectionDatabase_S2.ExecuteSQL(booksSql);
            connectionDatabase_S2.Dispose();
        }
        private void DeleteNode(EntityCode item)
        {

            ConnectionDatabase_S2 connectionDatabase_S2 = ConnectionDatabase_S2.BuildSqliteConnection(EntityDBFileName);
            var booksSql = item.BuildDeleteSql();
            connectionDatabase_S2.ExecuteSQL(booksSql);
            connectionDatabase_S2.Dispose();
        }
        #endregion

        #region 删除节点
        private void 删除节点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }
            var selNode = this.treeView1.SelectedNode;
            var dr = MessageBox.Show("是否删除节点:" + selNode.Text, "删除提醒?", MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                var nodesChildren = selNode.Nodes.Count;
                if (nodesChildren > 0)
                {
                    for (var i = selNode.Nodes.Count - 1; i >= 0; i--)
                    {
                        RemoveNode(selNode.Nodes[i]);
                    }
                }
                RemoveNode(selNode);
            }
        }
        /// <summary>
        /// 移除某个节点
        /// </summary>
        /// <param name="selNode"></param>
        private void RemoveNode(TreeNode selNode)
        {
            DeleteNode(selNode.Tag as EntityCode);
            if (selNode.Parent == null)
            {
                treeView1.Nodes.Remove(selNode);
            }
            else
            {
                selNode.Parent.Nodes.Remove(selNode);
            }
        }
        #endregion

        #region 移动节点
        private void 换父节点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }
            var selNode = this.treeView1.SelectedNode;

            this.toolStripStatusLabel1.Text = ("已选择节点:" + selNode.Text + ",请点击选择父节点。");

            m_isMoveNode = true;
            m_toMovingNode = selNode;
        }
        private TreeNode m_toMovingNode;
        private bool m_isMoveNode = false;
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var currentNode = e.Node;
            if (m_isMoveNode)
            {
                var dr = MessageBox.Show("已选择节点:" + m_toMovingNode.Text + ",是否移动到节点 " + currentNode + " 下面？", "移动", MessageBoxButtons.YesNoCancel);
                if (dr == DialogResult.Yes)
                {
                    MoveNode(m_toMovingNode, currentNode);
                }
                if (dr == DialogResult.No)
                {
                    return;
                }
                if (dr == DialogResult.Cancel)
                {
                    m_isMoveNode = false;
                    return;
                }
            }
        }
        /// <summary>
        /// 将toMovingNode改为currentNode的儿子
        /// </summary>
        /// <param name="toMovingNode"></param>
        /// <param name="currentNode"></param>
        private void MoveNode(TreeNode toMovingNode, TreeNode currentNode)
        {
            if (toMovingNode.Parent == null)
            {
                treeView1.Nodes.Remove(toMovingNode);
            }
            else
            {
                toMovingNode.Parent.Nodes.Remove(toMovingNode);
            }
            currentNode.Nodes.Add(toMovingNode);
            m_isMoveNode = false;

            (toMovingNode.Tag as EntityCode).ParentId = (currentNode.Tag as EntityCode).Id;
            SaveUpdate((toMovingNode.Tag as EntityCode));
        }
        #endregion

        #region 按顺序进行编码
        private void 从本节点往下顺序编号ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }
            var selNode = this.treeView1.SelectedNode;
            if (selNode.Parent == null) return;
            var t = selNode.Parent.Nodes.IndexOf(selNode);

            var maxCodeLenght = new int[10];
            for (var i = 0; i < selNode.Parent.Nodes.Count; i++)
            {
                var selNodeMe = selNode.Parent.Nodes[i];
                var ec = selNodeMe.Tag as EntityCode;
                maxCodeLenght[ec.CodeValue.Split('.')[0].Length]++;
            }
            var mCodeLength = 0;
            var mCodeIndex = 2;
            for (var i = 0; i < maxCodeLenght.Length; i++)
            {
                if (mCodeLength < maxCodeLenght[i])
                {
                    mCodeLength = maxCodeLenght[i];
                    mCodeIndex = i;
                }
            }

            for (var i = t; i < selNode.Parent.Nodes.Count; i++)
            {
                var selNodeMe = selNode.Parent.Nodes[i];
                var ec = selNodeMe.Tag as EntityCode;
                ec.CodeValue = (i + 1).ToString().PadLeft(mCodeIndex, '0');
                SaveUpdate(ec);

                selNodeMe.Text = ec.ToString();
            }
        }
        #endregion

        #region 搜索
        private List<TreeNode> m_searchedItems = new List<TreeNode>();
        private int m_currentSearchIndex = 0;
        private TreeNode m_lastSelectHighlightItem = null;
        private void button1_Click(object sender, EventArgs e)
        {
            var findItem = this.textBox1.Text.Trim();
            m_searchedItems.Clear();
            if (string.IsNullOrEmpty(findItem)) { return; }
            for (var i = 0; i < this.treeView1.Nodes.Count; i++)
            {
                var ec = this.treeView1.Nodes[i].Tag as EntityCode;
                if (ec.Name.IndexOf(findItem) >= 0)
                {
                    m_searchedItems.Add(this.treeView1.Nodes[i]);
                }
                SearchChildNode(this.treeView1.Nodes[i], findItem);
            }

            if (m_searchedItems.Count > 0)
            {
                this.treeView1.SelectedNode = m_searchedItems[0];
                m_searchedItems[0].EnsureVisible();
                m_currentSearchIndex = 0;

                HighlightItem();
            }
        }

        private void HighlightItem()
        {
            if (m_lastSelectHighlightItem != null)
            {
                m_lastSelectHighlightItem.BackColor = Color.White;
            }
            if (this.treeView1.SelectedNode != null)
            {
                this.treeView1.SelectedNode.BackColor = Color.LightGoldenrodYellow;
            }

            m_lastSelectHighlightItem = this.treeView1.SelectedNode;
        }

        private void SearchChildNode(TreeNode tn, string findItem)
        {
            for (var i = 0; i < tn.Nodes.Count; i++)
            {
                var ec = tn.Nodes[i].Tag as EntityCode;
                if (ec.Name.IndexOf(findItem) >= 0)
                {
                    m_searchedItems.Add((TreeNode)tn.Nodes[i]);
                }
                SearchChildNode(tn.Nodes[i], findItem);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            m_currentSearchIndex++;
            if (m_currentSearchIndex >= m_searchedItems.Count)
            {
                m_currentSearchIndex = 0;
            }
            this.treeView1.SelectedNode = m_searchedItems[m_currentSearchIndex];
            m_searchedItems[m_currentSearchIndex].EnsureVisible();
            HighlightItem();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            m_currentSearchIndex--;
            if (m_currentSearchIndex < 0)
            {
                m_currentSearchIndex = m_searchedItems.Count - 1;
            }
            this.treeView1.SelectedNode = m_searchedItems[m_currentSearchIndex];
            m_searchedItems[m_currentSearchIndex].EnsureVisible();
            HighlightItem();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.textBox1.Text = "";
            this.treeView1.SelectedNode = null;
            m_searchedItems.Clear();
            HighlightItem();
        }
        #endregion

        #region 导出Excel
        private void 导出CSV表格ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ExportCSV(null);
        }
        private void 导出选中ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var treeNode = this.treeView1.SelectedNode;
            if (treeNode.Parent != null)
            {
                MessageBox.Show("请选中一个大节点");
                return;
            }
            List<TreeNode> nodes = new List<TreeNode>();
            nodes.Add(treeNode);
            ExportCSV(nodes);
        }
        private void ExportCSV(List<TreeNode> filterNodes)
        {
            string localFilePath = "";
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Excel表格（*.xlsx）|*.xlsx";
            sfd.RestoreDirectory = true;

            try
            {
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    localFilePath = sfd.FileName.ToString(); //获得文件路径 
                    ExportExcel.ExportTreeViewToExcel(treeView1, localFilePath, filterNodes);
                    MessageBox.Show("导出成功");
                }
            }
            catch (Exception error)
            {
                MessageBox.Show($"导出失败：{error}");
            }
        }

        private void Write(StringBuilder sb, TreeNode node, string lastStr)
        {
            var currrentStr = "";
            if (lastStr == null)
            {
                currrentStr = Regex.Replace(node.Text, ",", "、");
            }
            else
            {
                currrentStr = lastStr + "," + Regex.Replace(node.Text, ",", "、");
            }

            sb.AppendLine(currrentStr);
            foreach (var item in node.Nodes)
            {
                var cNode = item as TreeNode;
                Write(sb, cNode, currrentStr);
            }
        } 
        #endregion

        private void treeView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyCode == Keys.F2)
            {
                修改ToolStripMenuItem_Click(null, null);
            }
        }

        private void 编码规则ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EntityFullCodeForm form = new EntityFullCodeForm();
            form.StartPosition = FormStartPosition.CenterParent;
            form.Show();
        }

        private void 移除本节点tipsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null) { return; }
            var selNode = this.treeView1.SelectedNode;

            var br = MessageBox.Show("将移除选中的节点" + selNode.Text + "，并且把该节点的儿子转换为自己父亲的儿子。", "移除提示", MessageBoxButtons.OKCancel);
            if (br != DialogResult.OK)
            {
                return;
            }
            var parentNode = selNode.Parent;

            for (var i = selNode.Nodes.Count - 1; i >= 0; i--)
            {
                var q = i.ToString();
                if (selNode.Nodes.Count > 100)
                {
                    q = i.ToString().PadLeft(3, '0');
                }
                else if (selNode.Nodes.Count > 10)
                {
                    q = i.ToString().PadLeft(2, '0');
                }
                else
                {
                    q = i.ToString().PadLeft(1, '0');
                }
                var cenc = (selNode.Nodes[i].Tag as EntityCode);
                var penc = (selNode.Tag as EntityCode);
                cenc.CodeValue = penc.CodeValue + "." + q;
                cenc.Description = (cenc.Description + "\r\n" + penc.Name).Trim();
                selNode.Nodes[i].Text = cenc.ToString();
                MoveNode(selNode.Nodes[i], parentNode);
                SortTree(parentNode, 0, 0);
            }
        }

        private void 基于CSV验证ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog()
            {
                Filter = "Excel表格（*.xlsx）|*.xlsx",
                Title = "请选择一个excel文件"
            };

            if (open.ShowDialog() == DialogResult.OK)
            {
                string filePath = open.FileName;
                EntityDataForm entityDataForm = new EntityDataForm(filePath, treeView1);
                entityDataForm.ShowDialog();
            }
        }

       
    }
}
